package com.tianji.learning.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.tianji.api.cache.CategoryCache;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.client.search.SearchClient;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.QuestionAdminPageQuery;
import com.tianji.learning.domain.dto.QuestionFormDTO;
import com.tianji.learning.domain.dto.QuestionPageQuery;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.vo.QuestionAdminVO;
import com.tianji.learning.domain.vo.QuestionVO;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.service.IInteractionQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动提问的问题表 服务实现类
 * </p>
 *
 * @author taohongrun
 * @since 2025-02-06
 */
@Service
@RequiredArgsConstructor
public class InteractionQuestionServiceImpl extends ServiceImpl<InteractionQuestionMapper, InteractionQuestion> implements IInteractionQuestionService {

    private final UserClient userClient;
    private final SearchClient searchClient;
    private final CourseClient courseClient;
    private final CatalogueClient catalogueClient;
    private final CategoryCache categoryCache;
    @Override
    public void updateQuestion(Long id, QuestionFormDTO questionFormDTO) {
       InteractionQuestion interactionQuestion = BeanUtil.copyProperties(questionFormDTO,InteractionQuestion.class);
       interactionQuestion.setId(id);
       updateById(interactionQuestion);
    }

    @Override
    public PageDTO<QuestionVO> queryQuestionPage(QuestionPageQuery query) {
        // 1.参数校验，课程id和userid不能都为空
        Long userId = UserContext.getUser();
        if(userId==null) throw new BadRequestException("用户未登录");
        Long courseId = query.getCourseId();
        if (courseId == null ) throw new BadRequestException("课程id和小节id不能都为空");

        //分页查询 提问基本信息
        Page<InteractionQuestion> page = lambdaQuery()
                .select(InteractionQuestion.class, info -> !info.getProperty().equals("description"))
                .eq(InteractionQuestion::getCourseId, query.getCourseId())
                .eq(query.getSectionId() != null, InteractionQuestion::getSectionId, query.getSectionId())
                .eq(query.getOnlyMine(), InteractionQuestion::getUserId, userId)
                .eq(InteractionQuestion::getHidden, false)
                .orderByDesc(InteractionQuestion::getCreateTime)
                .page(query.toMpPage());
        List<InteractionQuestion> interactionQuestions = page.getRecords();
        //若数据不存在，直接返回
        if(interactionQuestions == null) return PageDTO.empty(page);

        //根据最近回答id查询对应的回答信息转Map，用于封装Vo
        List<Long> replyIds = interactionQuestions.stream().map(InteractionQuestion::getLatestAnswerId)
                .filter(Objects::nonNull) // 过滤掉null值
                .collect(Collectors.toList());
        Map<Long, InteractionReply> latestReplyMap = null;
        List<Long> userIds ;
        List<Long> questionUserIds = interactionQuestions.stream().map(InteractionQuestion::getUserId).distinct().collect(Collectors.toList());
        // 一定要分类，否则reply为null时，后续调用报空指针异常
        if (!CollUtil.isEmpty(replyIds)){
            //获取 问题提问用户id 以及 最近回答的用户id 合并
            List<InteractionReply> replyList = Db.lambdaQuery(InteractionReply.class).in(InteractionReply::getId,replyIds).list();
            latestReplyMap = replyList.stream().collect(Collectors.toMap(InteractionReply::getId, reply -> reply));
            List<Long> replyUserIds = replyList.stream().map(InteractionReply::getUserId).collect(Collectors.toList());
            userIds = (List<Long>) CollUtil.union(replyUserIds, questionUserIds);
        }else {
            userIds = questionUserIds;
        }
        //获取会用到的所有userId，并获取完整信息，转为Map，用于封装Vo
        List<UserDTO> users = userClient.queryUserByIds(userIds);
        Map<Long, UserDTO> userMap = users.stream().collect(Collectors.toMap(UserDTO::getId, u -> u));

        //封装Vo
        List<QuestionVO> questionVOS = new ArrayList<>();
        for(InteractionQuestion interactionQuestion : interactionQuestions){
            QuestionVO questionVO = new QuestionVO();
            BeanUtils.copyProperties(interactionQuestion,questionVO);
            if (!BooleanUtil.isTrue(interactionQuestion.getAnonymity())){
                UserDTO userDTO = userMap.get(interactionQuestion.getUserId());
                questionVO.setUserIcon(userDTO.getIcon());
                questionVO.setUserName(userDTO.getName());
            }
            if (latestReplyMap != null){
                InteractionReply interactionReply = latestReplyMap.get(interactionQuestion.getLatestAnswerId());
                if (!BooleanUtil.isTrue(interactionReply.getAnonymity())){
                    questionVO.setLatestReplyContent(interactionReply.getContent());
                    questionVO.setLatestReplyUser(userMap.get(interactionReply.getUserId()).getName());
                }
            }
            questionVOS.add(questionVO);
        }
        return PageDTO.of(page,questionVOS);
    }

    @Override
    public void saveQuestion(QuestionFormDTO questionDTO) {
        InteractionQuestion interactionQuestion = new InteractionQuestion();
        BeanUtils.copyProperties(questionDTO,interactionQuestion);
        Long userId = UserContext.getUser();
        if(userId == null) throw new BadRequestException("用户未登录");
        interactionQuestion.setUserId(userId);
        save(interactionQuestion);
    }

    @Override
    public QuestionVO queryQuestionById(Long id) {
        // 1.根据id查询数据
        InteractionQuestion question = getById(id);
        // 2.数据校验
        if(question == null || question.getHidden()){
            // 没有数据或者是被隐藏了
            return null;
        }
        // 3.查询提问者信息
        UserDTO user = null;
        if(!question.getAnonymity()){
            user = userClient.queryUserById(question.getUserId());
        }
        // 4.封装VO
        QuestionVO vo = BeanUtil.copyProperties(question, QuestionVO.class);
        if (user != null) {
            vo.setUserName(user.getName());
            vo.setUserIcon(user.getIcon());
        }
        return vo;
    }

    @Override
    public PageDTO<QuestionAdminVO> queryQuestionPageAdmin(QuestionAdminPageQuery query) {
        // 1.处理课程名称，得到课程id
        boolean notBlank = StrUtil.isNotBlank(query.getCourseName());
        List<Long> courseIds = null;
        if (notBlank) {
            courseIds = searchClient.queryCoursesIdByName(query.getCourseName());
            if (CollUtils.isEmpty(courseIds)) {
                return PageDTO.empty(0L, 0L);
            }
        }
        Integer status = query.getStatus();
        LocalDateTime begin = query.getBeginTime();
        LocalDateTime end = query.getEndTime();
        Page<InteractionQuestion> page = lambdaQuery()
                .in(notBlank, InteractionQuestion::getCourseId, courseIds)
                .eq(status != null, InteractionQuestion::getStatus, status)
                .gt(begin != null, InteractionQuestion::getCreateTime, begin)
                .lt(end != null, InteractionQuestion::getCreateTime, end)
                .orderByDesc(InteractionQuestion::getCreateTime)
                .page(query.toMpPage());
        List<InteractionQuestion> records = page.getRecords();
        if (CollUtils.isEmpty(records)) {
            return PageDTO.empty(page);
        }
        // 3.准备VO需要的数据：用户数据、课程数据、章节数据
        Set<Long> userIds = new HashSet<>();
        Set<Long> cIds = new HashSet<>();
        Set<Long> cataIds = new HashSet<>();
        // 3.1.获取各种数据的id集合
        for (InteractionQuestion q : records) {
            userIds.add(q.getUserId());
            cIds.add(q.getCourseId());
            cataIds.add(q.getChapterId());
            cataIds.add(q.getSectionId());
        }
        // 3.2.根据id查询用户
        List<UserDTO> users = userClient.queryUserByIds(userIds);
        Map<Long, UserDTO> userMap = new HashMap<>(users.size());
        if (CollUtils.isNotEmpty(users)) {
            userMap = users.stream().collect(Collectors.toMap(UserDTO::getId, u -> u));
        }

        // 3.3.根据id查询课程
        List<CourseSimpleInfoDTO> cInfos = courseClient.getSimpleInfoList(cIds);
        Map<Long, CourseSimpleInfoDTO> cInfoMap = new HashMap<>(cInfos.size());
        if (CollUtils.isNotEmpty(cInfos)) {
            cInfoMap = cInfos.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, c -> c));
        }

        // 3.4.根据id查询章节
        List<CataSimpleInfoDTO> catas = catalogueClient.batchQueryCatalogue(cataIds);
        Map<Long, String> cataMap = new HashMap<>(catas.size());
        if (CollUtils.isNotEmpty(catas)) {
            cataMap = catas.stream()
                    .collect(Collectors.toMap(CataSimpleInfoDTO::getId, CataSimpleInfoDTO::getName));
        }


        // 4.封装VO
        List<QuestionAdminVO> voList = new ArrayList<>(records.size());
        for (InteractionQuestion q : records) {
            // 4.1.将PO转VO，属性拷贝
            QuestionAdminVO vo = BeanUtil.copyProperties(q, QuestionAdminVO.class);
            voList.add(vo);
            // 4.2.用户信息
            UserDTO user = userMap.get(q.getUserId());
            if (user != null) {
                vo.setUserName(user.getName());
            }
            // 4.3.课程信息以及分类信息
            CourseSimpleInfoDTO cInfo = cInfoMap.get(q.getCourseId());
            if (cInfo != null) {
                vo.setCourseName(cInfo.getName());
                vo.setCategoryName(categoryCache.getCategoryNames(cInfo.getCategoryIds()));
            }
            // 4.4.章节信息
            vo.setChapterName(cataMap.getOrDefault(q.getChapterId(), ""));
            vo.setSectionName(cataMap.getOrDefault(q.getSectionId(), ""));
        }
        return PageDTO.of(page, voList);
    }
}
